package com.ihrm.system.service;

import com.ihrm.common.entity.Result;
import com.ihrm.common.entity.ResultCode;
import com.ihrm.common.exception.CommonException;
import com.ihrm.common.utils.BeanMapUtils;
import com.ihrm.common.utils.IdWorker;
import com.ihrm.common.utils.PermissionConstants;
import com.ihrm.domain.system.*;
import com.ihrm.system.mapper.PermissionApiDao;
import com.ihrm.system.mapper.PermissionDao;
import com.ihrm.system.mapper.PermissionMenuDao;
import com.ihrm.system.mapper.PermissionPointDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Transactional
@Service
public class PermissionService {

	@Autowired
	private PermissionDao permissionDao;

	@Autowired
	private PermissionMenuDao permissionMenuDao;

	@Autowired
	private PermissionPointDao permissionPointDao;

	@Autowired
	private PermissionApiDao permissionApiDao;

	@Autowired
	private IdWorker idWorker;

	/**
	 * 添加权限
	 */
	public Result save(Map<String, Object> map) throws Exception {
		String id=idWorker.nextId()+"";
		//通过map构造permission对象
		Permission permission = BeanMapUtils.mapToBean(map, Permission.class);
		permission.setId(id);
		//根据类型不同构造不同的资源对象（菜单、按钮、API）
		int type = permission.getType();
		switch (type) {
			case PermissionConstants.PY_MENU:
				PermissionMenu menu = BeanMapUtils.mapToBean(map, PermissionMenu.class);
				menu.setId(id);
				permissionMenuDao.save(menu);
				break;
			case PermissionConstants.PY_POINT:
				PermissionPoint point = BeanMapUtils.mapToBean(map, PermissionPoint.class);
				permissionPointDao.save(point);
				break;
			case PermissionConstants.PY_API:
				PermissionApi  api = BeanMapUtils.mapToBean(map, PermissionApi.class);
				api.setId(id);
				permissionApiDao.save(api);
				break;
			default:
				throw new CommonException(ResultCode.FAIL);

		}
		//保存权限
		permissionDao.save(permission);
		return Result.SUCCESS();
	}

	/**
	 * 查询所有权限
	 * type: 0:菜单+按钮(权限)  1:菜单 2:按钮 3:API
	 * enVisible: 0:查询所有saas平台的最高权限  1:查询本企业的权限
	 * pid: 父id
	 */
	public List<Permission> findAll(Map<String,Object> map) {
		//1.需要查询条件
		Specification<Permission> spec = new Specification<Permission>() {

			/**
			 * 动态拼接查询条件
			 * @param root
			 * @param query
			 * @param cb
			 * @return
			 */
			@Override
			public Predicate toPredicate(Root<Permission> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				List<Predicate> list = new ArrayList<>();
				//根据请求的pid是否为空构造查询条件
				if(!StringUtils.isEmpty(map.get("pid"))){
					list.add(cb.equal(root.get("pid").as(String.class),(String)map.get("pid")));
				}

				//根据请求的enVisible是否为空构造查询条件
				if(!StringUtils.isEmpty(map.get("enVisible"))){
					list.add(cb.equal(root.get("enVisible").as(String.class),(String)map.get("enVisible")));
				}

				//根据类型type构造查询条件
				if(!StringUtils.isEmpty(map.get("type"))){
					//根据请求的type判断 0菜单+按钮 1菜单 2按钮 3接口api
					String type = (String)map.get("type");
					CriteriaBuilder.In<Object> in = cb.in(root.get("type"));
					if("0".equals(type)){
						in.value(1).value(2);
					}else{
						in.value(Integer.parseInt(type));
					}
				}
				return cb.and(list.toArray(new Predicate[list.size()]));
			}
		};
		return permissionDao.findAll(spec);

	}

	/**
	 * 根据id查询权限
	 *
	 *   //1.查询权限
	 *   //2.根据权限类型查询资源
	 *   //3.构造map集合
	 */
	public Map<String,Object> findById(String id) throws Exception {
		Permission permissionDb =permissionDao.findById(id).get();
		int type = permissionDb.getType();

		Object object = null;
		if(type == PermissionConstants.PY_MENU){
			object = permissionMenuDao.findById(id).get();
		}else if(type == PermissionConstants.PY_POINT){
			object = permissionPointDao.findById(id).get();
		} else if(type==PermissionConstants.PY_API) {
			object = permissionApiDao.findById(id).get();
		}else {
			throw new CommonException(ResultCode.FAIL);
		}
		Map<String, Object> map = BeanMapUtils.beanToMap(object);
		map.put("name", permissionDb.getName());
		map.put("type", permissionDb.getType());
		map.put("code", permissionDb.getCode());
		map.put("description", permissionDb.getDescription());
		map.put("pid", permissionDb.getPid());
		map.put("enVisible", permissionDb.getEnVisible());

		return map;
	}

	/**
	 * 更新权限
	 */
	public Result update(Map<String, Object> map) throws Exception {
		//通过传递的权限id查询权限 先查再改

		Permission permission = BeanMapUtils.mapToBean(map, Permission.class);
		String id= permission.getId();
		Permission permissionDb = permissionDao.findById(permission.getId()).get();
		permissionDb.setName(permission.getName());
		permissionDb.setCode(permission.getCode());
		permissionDb.setDescription(permission.getDescription());

		//2.根据类型构造不同的资源
		int type = permissionDb.getType();
		switch (type) {
			case PermissionConstants.PY_MENU:
				PermissionMenu menu = BeanMapUtils.mapToBean(map, PermissionMenu.class);
				menu.setId(id);
				permissionMenuDao.save(menu);
				break;
			case PermissionConstants.PY_POINT:
				PermissionPoint point = BeanMapUtils.mapToBean(map, PermissionPoint.class);
				permissionPointDao.save(point);
				break;
			case PermissionConstants.PY_API:
				PermissionApi  api = BeanMapUtils.mapToBean(map, PermissionApi.class);
				api.setId(id);
				permissionApiDao.save(api);
				break;
			default:
				throw new CommonException(ResultCode.FAIL);

		}
		//3.保存权限
		permissionDao.save(permissionDb);

		return Result.SUCCESS();
	}

	/**
	 * 删除权限
	 * 1.删除权限
	 * 2.删除权限对应的资源
	 */
	public Result delete(String id) throws CommonException {
		Permission permissionDb = permissionDao.findById(id).get();
		permissionDao.delete(permissionDb);
		//2.根据类型构造不同的资源
		int type = permissionDb.getType();
		switch (type) {
			case PermissionConstants.PY_MENU:
				permissionMenuDao.deleteById(id);
				break;
			case PermissionConstants.PY_POINT:
				permissionPointDao.deleteById(id);
				break;
			case PermissionConstants.PY_API:
				permissionApiDao.deleteById(id);
				break;
			default:
				throw new CommonException(ResultCode.FAIL);
		}
		return new Result(ResultCode.SUCCESS);
	}
}
